package com.ccys.cms.advice;

import com.ccys.common.util.Kit;
import com.ccys.db.cache.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.RequestUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: OrderByAdvice
 * @Description:
 * @Author: CB
 * @Date: 2023/12/11 14:09
 */
@Slf4j
@Aspect
@Component
@Order(1)
public class OrderByAdvice {

    //orderBy防注入校验
    private static final String[] ORDER_BY_STR_INVALID_ARR = new String[]{";","=","--","'"," "};
    private static List<String> ORDER_BY_METHOD_LIST;
    private static final String ORDER_BY_STR = "orderByStr";

    static {
        ORDER_BY_METHOD_LIST = new ArrayList<>();
        ORDER_BY_METHOD_LIST.add("ascend");
        ORDER_BY_METHOD_LIST.add("descend");
    }

    @Pointcut(value = "execution(* com.ccys.cms.controller.*.*..*(..))")
    private void orderByCut() {

    }

    @Before("orderByCut()")
    public void setShopIdOrDateStr(JoinPoint joinPoint) {
        try {
            //校验
            Map<String, String[]> parameterMap = Kit.getRequest().getParameterMap();
            String[] params = parameterMap.get(ORDER_BY_STR);
            if(params==null){
                return;
            }
            String orderByStr = params[0];
            if(StringUtils.isNotBlank(orderByStr)){
                boolean flag = true;
                String[] arr = orderByStr.split(" ");
                if(arr.length!=2 || !ORDER_BY_METHOD_LIST.contains(arr[1])){
                    flag = false;
                }else{
                    for (String s : ORDER_BY_STR_INVALID_ARR) {
                        if(arr[0].contains(s)){
                            flag = false;
                        }
                    }
                }
                //加上该校验  groupStatus 字段会出问题
                /*try {
                    Base64.getDecoder().decode(arr[0]);
                    flag = false;
                }catch (Exception e){

                }*/

                Object[] objects = joinPoint.getArgs();
                if (objects != null) {
                    int index = objects.length - 1;
                    if (index >= 0) {
                        Object object = objects[index];
                        if (object == null) {
                            return;
                        }
                        Class<?> clazz = object.getClass();
                        if(parameterMap.get(ORDER_BY_STR)==null){
                            return;
                        }
                        Field fieldOrderStr = ReflectionUtils.findField(clazz, "orderByStr");
                        if(fieldOrderStr!=null){
                            Method m = clazz.getMethod("setOrderByStr", String.class);
                            if (m != null) {
                                m.setAccessible(true);
                                if(flag){
                                    //orderByStr 校验通过
                                    orderByStr = orderByStr.replaceAll("ascend","asc").replaceAll("descend","desc");
                                }else{
                                    log.error("orderByStr格式异常！{}",orderByStr);
                                    orderByStr = null;
                                }
                                m.invoke(object, orderByStr);
                            }
                        }
                    }
                }

            }

        }catch (Exception e){
            log.error("获取排序参数异常",e);
        }
    }
}
